package com.terry.gamesupport.config;

import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.XSlf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.annotation.EnableRabbit;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.amqp.RabbitProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;

@Configuration
@EnableRabbit
public class MyRabbitConfig {
    protected Logger logger = LoggerFactory.getLogger(getClass());

    //设置传输对象转化为json
    @Bean
    public MessageConverter messageConverter() {
        return new Jackson2JsonMessageConverter();
    }

    @Autowired
    AmqpAdmin amqpAdmin;

    @Autowired
    RabbitTemplate rabbitTemplate;

    public void createExchange() {
        //DirectExchange(String name, boolean durable, boolean autoDelete, Map<String, Object> arguments)
        DirectExchange directExchange = new DirectExchange("hello-java-exchange", true, false);
        amqpAdmin.declareExchange(directExchange);
        System.out.println("消息交换hello-java-exchange 创建成功！");
    }

    public void createQueue() {
        // Queue(String name, boolean durable, boolean exclusive, boolean autoDelete, @Nullable Map<String, Object> arguments)
        Queue queue = new Queue("hello-java-queue", true, false, false);
        amqpAdmin.declareQueue(queue);
    }

    public void createBinding() {
        //Binding(String destination, Binding.DestinationType destinationType, String exchange, String routingKey, @Nullable Map<String, Object> arguments)
        Binding binding = new Binding("hello-java-queue", Binding.DestinationType.QUEUE, "hello-java-exchange", "hello.java", null);
        amqpAdmin.declareBinding(binding);
    }

    public void sendMessage() {
        rabbitTemplate.convertAndSend("hello-java-exchange", "hello.java", "hello.java");
        logger.info("发送消息成功");
    }


    /**
     * 参数可以写一下类型
     * 1.Message message:原生消息详细信息。 头+体
     * 2.发送的消息类型
     *
     * @param message
     */
//    @RabbitListener(queues = {"hello-java-queue"})
//    public void receiveMessage(Message message, String msg, Channel channel) throws Exception{
//        //消费端确认机制
//        //1.默认自动确认，消息接收到，就自动移除
//        //问题收到很多消息，服务器宕机消息丢失
//        //手动确认
//        long deliveryTag = message.getMessageProperties().getDeliveryTag();
//        //签收，非批量模式
//        try {
//            channel.basicAck(deliveryTag, false);
//        } catch (Exception e) {
//            //拒收消息，非批量模式,消息再入队
//            channel.basicNack(deliveryTag,false,true);
//            //拒绝签收,消息再入队
//            channel.basicReject(deliveryTag,true);
//        }
//    }

    //对象创建完成以后调用
    //消息只要抵达服务器就是true
    @PostConstruct
    public void initRabbitTemplate() {
        //设置确认回调
        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            /**
             * @param correlationData 当前消息的唯一关联数据
             * @param ack 消息是否成功收到
             * @param cause 消息失败的原因
             */
            @Override
            public void confirm(CorrelationData correlationData, boolean ack, String cause) {
                System.out.println("comfirm->" + correlationData + "-->" + ack + "-->" + cause);
            }
        });

        //设置消息抵达队列确认回调
        rabbitTemplate.setReturnsCallback(new RabbitTemplate.ReturnsCallback() {
            @Override
            public void returnedMessage(ReturnedMessage returnedMessage) {
                logger.info("消息未抵达队列！", returnedMessage);
            }
        });
    }


    //
}


